package config

import (
	"cade/src/core"
	"cade/src/core/log"
	"encoding/json"
	"io/ioutil"
	"regexp"
	"strings"
)

// ============================================================================

type common_t struct {
	Version     string `json:"version"`
	Ver_Major   string `json:"-"`
	Ver_Minor   string `json:"-"`
	Ver_Build   string `json:"-"`
	DBCenter    string `json:"db_center"`
	BehindProxy bool   `json:"behind_proxy"`
	DevMode     bool   `json:"dev_mode"`
}

type game_t struct {
	Id      int32  `json:"-"`
	Name    string `json:"-"`
	Addr4GW string `json:"addr4gw"`
}

type gate_t struct {
	Id     int32  `json:"-"`
	Name   string `json:"-"`
	IPWan  string `json:"ip_wan"`
	Port   int32  `json:"port"`
	WsPort int32  `json:"wsport"`
}

// ============================================================================

type config_t struct {
	Common *common_t          `json:"common"`
	Games  map[string]*game_t `json:"games"`
	Gates  map[string]*gate_t `json:"gates"`
}

// ============================================================================

var (
	Common *common_t
	Games  map[string]*game_t
	Gates  map[string]*gate_t
)

var (
	CurGame *game_t
	CurGate *gate_t
)

// ============================================================================

func Parse(fn string, server string) {
	defer func() {
		if err := recover(); err != nil {
			log.Warning(err)
		}
	}()

	var conf config_t

	// read file
	d, err := ioutil.ReadFile(fn)
	if err != nil {
		core.Panic("open config file failed:", err)
	}

	// parse
	err = json.Unmarshal(d, &conf)
	if err != nil {
		core.Panic("parse config file failed:", err)
	}

	parse_id_name(&conf)
	parse_version(&conf)

	// set variables
	Common = conf.Common
	Games = conf.Games
	Gates = conf.Gates

	// set current
	func() {
		for k, v := range Games {
			if k == server {
				CurGame = v
				return
			}
		}

		for k, v := range Gates {
			if k == server {
				CurGate = v
				return
			}
		}
	}()
}

// ============================================================================

func parse_id_name(conf *config_t) {
	re := regexp.MustCompile(`^[a-z]+(\d+)$`)

	for k, v := range conf.Games {
		arr := re.FindStringSubmatch(k)
		if arr == nil || len(arr) < 2 {
			core.Panic("invalid game name:", k)
		}

		v.Id = core.Atoi32(arr[1])
		v.Name = k
	}

	for k, v := range conf.Gates {
		arr := re.FindStringSubmatch(k)
		if arr == nil || len(arr) < 2 {
			core.Panic("invalid gate name:", k)
		}

		v.Id = core.Atoi32(arr[1])
		v.Name = k
	}
}

func parse_version(conf *config_t) {
	arr := strings.Split(conf.Common.Version, ".")
	if len(arr) < 3 {
		core.Panic("invalid version:", conf.Common.Version)
	}

	conf.Common.Ver_Major = arr[0]
	conf.Common.Ver_Minor = arr[1]
	conf.Common.Ver_Build = arr[2]
}
